<template>
  <div class="console" v-show="musicList.length">
    <audio
      ref="musicAudio"
      :src="currentMusic.src"
      @canplay="handleCanPlay"
      @timeupdate="handleTimeUpdate"
      @ended="handleEnded"
    />
    <el-slider :model-value="sliderValue" :show-tooltip="false" @input="slideChange" />
    <div class="content pd-lr40 d-flex">
      <div class="left">
        <span
          ref="el"
          class="font-14 text-nowrap singerNameBox"
          :style="{
            animation: flowWidth ? 'singerNameMove 10s linear infinite' : '',
            transform: flowWidth ? 'translateX(10px)' : ''
          }"
        >
          <span>
            {{ currentMusic.name }}
          </span>
          <span class="pd-lr5" style="color: #7b7b7b">-</span>
          <span style="color: #7b7b7b">{{ currentMusic.singerName }}</span>
        </span>
        <div class="d-flex a-center pd-t3">
          <love v-model="currentMusic.isLike" />
          <span class="comment music-hover iconfont font-19 pd-l10">&#xe69c;</span>
        </div>
      </div>
      <div class="center flex-1 d-flex">
        <div class="flex-1">频谱</div>
        <div class="d-flex j-center a-center">
          <el-popover :visible="visible" placement="top" :width="80" popper-class="pd-3">
            <div
              v-for="item in playMode"
              :key="item.icon"
              class="mode-item d-flex a-center pd-lr15 pointer"
              @click="modeChange(item)"
            >
              <span class="iconfont font-22 pd-r10" :class="item.icon"></span>
              <span>{{ item.text }}</span>
            </div>
            <template #reference>
              <span
                class="play-mode iconfont pointer font-22"
                :class="currentModel.icon"
                @click="openPopover"
                :title="currentModel.text"
              />
            </template>
          </el-popover>

          <el-tooltip effect="light" content="上一首 Ctrl+Alt+Left">
            <span class="iconfont font-30 pd-lr20 pointer" @click="prevSong">&#xe63c;</span>
          </el-tooltip>

          <el-tooltip effect="light" :content="isPlay ? '暂停 Ctrl+Alt+F5' : '播放 Ctrl+Alt+F5'">
            <div class="play-pause pointer" @click="playChange(!isPlay)">
              <span class="iconfont" v-if="isPlay">&#xe87a;</span>
              <span class="iconfont pd-l4" v-else>&#xe87c;</span>
            </div>
          </el-tooltip>
          <el-tooltip effect="light" content="下一首 Ctrl+Alt+Right">
            <span class="iconfont font-30 pd-lr20 pointer" @click="nextSong">&#xe63e;</span>
          </el-tooltip>

          <el-tooltip effect="light">
            <template #content>
              <div>音量: 100%</div>
              <div>增大音量: Ctrl+Alt+Up</div>
              <div>减少音量: Ctrl+Alt+Down</div>
            </template>
            <span class="iconfont font-20 pointer">&#xea0d;</span>
          </el-tooltip>
        </div>
        <div class="flex-1 lyricBox">
          <div class="lyricContent" v-show="isWord" :style="{ top: lyricRoll.top + 'px' }">
            <div v-for="(item, index) in currentMusic.lyricList" :key="item.t" class="lyricItem">
              <div class="lyricText text-nowrap">
                {{ item.c }}
                <div
                  class="lyricGradient"
                  :style="{
                    animationName: lyricRoll.index === index ? 'move' : '',
                    animationDuration: item.transition + 's',
                    animationPlayState: lyricRoll.index === index && isPlay ? '' : 'paused'
                  }"
                  :cust-attr="`lyricGradient${index}`"
                >
                  {{ item.c }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="d-flex a-center right">
        <span>{{ currentTime }}</span>
        <span class="pd-lr3">/</span>
        <span>{{ duration }}</span>
        <span
          class="words music-hover pd-lr10 pointer"
          :style="{ color: isWord ? '#1ece9c' : '#838383' }"
          @click="wordChange($event)"
        >
          词
        </span>
        <div class="music-hover" @click="openDrawer" :style="{ color: isPlay ? '#1ece9c' : '' }">
          <span class="iconfont">&#xe699;</span>
          <span class="font-14 pd-l2">{{ musicList.length }}</span>
        </div>
      </div>
    </div>
    <el-drawer :model-value="drawer" :with-header="false" size="20%">
      <div style="height: 100%">
        <div class="drawer-header">头部</div>
        <div class="drawer-content">
          <div
            class="drawer-item d-flex a-center pointer pd-tb10 pd-lr17"
            v-for="item in musicList"
            :key="item.id"
          >
            <div class="flex-1">
              <div class="pd-b7">{{ item.name }}</div>
              <div class="font-13" style="color: rgb(180, 180, 180)">{{ item.singerName }}</div>
            </div>
            <div class="flex-1 operation d-flex a-center">
              <span class="iconfont">&#xea6d;</span>
              <span class="iconfont">&#xe6a4;</span>
              <span class="iconfont">&#xe68f;</span>
            </div>
          </div>
        </div>
        <div class="drader-footer d-flex a-center j-end">
          <div class="music-hover" @click="closeDrawer">
            <span class="iconfont">&#xe699;</span>
            <span class="font-14 pd-2">{{ musicList.length }}</span>
          </div>
        </div>
      </div>
    </el-drawer>
  </div>
</template>
<script lang="ts" setup>
  import { reactive, ref, computed, ComputedRef, watch, nextTick, onMounted } from 'vue'
  import { useStore } from 'vuex'
  import love from '../components/love.vue'
  import handlePopover from '@/hooks/usePopover'
  import useFlowWidth from '@/hooks/useFlowWidth'
  import bus from '@/utils/bus'
  import { setProgress, getRandomNumBoth, analysisLrc } from '@/utils'
  import { addPlayHistory } from '@/api/song'
  import { playMode } from '@/utils/enum'
  const { visible, openPopover, closePopover } = handlePopover()
  const { visible: drawer, openPopover: openDrawer, closePopover: closeDrawer } = handlePopover()
  const el = ref(null)
  const { flowWidth } = useFlowWidth(el)

  // eslint-disable-next-line no-undef
  defineOptions({
    name: 'Console'
  })
  const store = useStore()
  // 播放器标签
  const musicAudio = ref<any>()
  // 总时长
  const duration = ref<string>('00:00')
  // 当前进度
  const timeStamp = ref<number>(0)
  const currentTime = ref<string>('00:00')
  const sliderValue = ref<number>(0)
  const slideChange = (val: number) => {
    sliderValue.value = val
    musicAudio.value.currentTime = (musicAudio.value.duration * val) / 100
  }
  // 当前播放的模式
  const currentModel = reactive({ text: '随机播放', icon: 'icon-suijibofang', key: 'random' })

  // 当前播放的音乐
  const currentMusic = computed(() => {
    let obj: any = {
      id: '',
      src: '',
      name: '',
      singerName: '',
      isLike: 0,
      lyric: '',
      lyricList: []
    }

    if (musicList.value.length && currentIndex.value > -1) {
      obj = musicList.value[currentIndex.value]
      obj.lyricList = analysisLrc(obj.lyric, obj.duration).ms
    }

    bus.emit('setCurrentSong', obj)
    return obj
  })

  // 歌词滚动的top值计算
  const lyricRoll: ComputedRef<{ top: number; index: number }> = computed(() => {
    let length = currentMusic.value.lyricList.filter((item: any) => item.t < timeStamp.value).length
    length = length <= 1 ? 0 : length - 1

    const dom: HTMLDivElement = document.querySelector(
      `.lyricGradient[cust-attr=lyricGradient${length}]`
    ) as HTMLDivElement
    if (dom) dom.style.animationPlayState = ''
    if (length) {
      // console.log(currentMusic.value.lyricList[length].c)
    }
    return {
      top: length * -21,
      index: length
    }
  })

  // 监听是否加载完成
  const handleCanPlay = () => {
    console.log('监听是否加载完成')
    duration.value = setProgress(musicAudio.value.duration)
    playChange(true)
  }
  const currentIndex = ref<number>(-1)

  // 播放完成
  const handleEnded = () => {
    // 记录播放历史
    addPlayHistory({
      userId: store.state.userInfo.userId,
      songId: currentMusic.value.id
    })

    // 根据当前播放模式来决定进行下一步的操作
    switch (currentModel.key) {
      case 'random':
        currentIndex.value = getRandomNumBoth(0, musicList.value.length)
        break
      case 'order':
        currentIndex.value = ++currentIndex.value % musicList.value.length
        break
      case 'loop':
        playChange(true)
        break
      case 'listLoop':
        break
    }

    playInit(currentIndex.value)
  }

  // 当音频一直在播放的时候
  const handleTimeUpdate = () => {
    const time = musicAudio.value.currentTime
    // 时间进度的同步
    timeStamp.value = time
    currentTime.value = setProgress(time)
    sliderValue.value = (time / musicAudio.value.duration) * 100
  }

  // 播放模式切换
  const modeChange = (item: any) => {
    Object.assign(currentModel, item)
    closePopover()
  }

  // 上一首
  const prevSong = () => {
    if (currentModel.key === 'random') {
      currentIndex.value = getRandomNumBoth(0, musicList.value.length)
    } else {
      currentIndex.value = --currentIndex.value % musicList.value.length
    }

    playInit(currentIndex.value)
  }

  // 下一首
  const nextSong = () => {
    if (currentModel.key === 'random') {
      currentIndex.value = getRandomNumBoth(0, musicList.value.length)
      console.log(currentIndex.value)
    } else {
      currentIndex.value = ++currentIndex.value % musicList.value.length
    }

    playInit(currentIndex.value)
  }

  const isPlay = ref(false)
  // 播放&暂停
  const playChange = (val: boolean) => {
    isPlay.value = val

    if (isPlay.value) {
      musicAudio.value.play()
    } else {
      setTimeout(() => {
        musicAudio.value.pause()
      }, 150)
    }

    bus.emit('playChange', isPlay.value)
  }

  // 对外提供一个暂停的方法
  bus.on('setPause', () => {
    playChange(false)
  })

  // 播放初始化
  bus.on('playInit', (index: any) => playInit(index))
  const playInit = (index: number) => {
    if (currentIndex.value === index) {
      playChange(true)
      return
    }
    currentIndex.value = index
    sliderValue.value = 0
  }

  // 播放队列
  const musicList = ref<any>([])
  bus.on('setMusicList', (data: any) => {
    musicList.value = data
  })

  const isWord = ref(true)
  const wordChange = (e: MouseEvent) => {
    isWord.value = !isWord.value
    e.target.style.transform = 'translate(1px, 1px)'
    setTimeout(() => {
      e.target.style.transform = 'translate(0)'
    }, 100)
  }

  // 按键事件监听
  document.onkeydown = (e: KeyboardEvent) => {
    const event: any = window.event
    const key = event.keyCode
    if (key === 37 && e.ctrlKey && e.altKey) {
      prevSong()
      event.preventDefault()
    }
    if ((key === 116 && e.ctrlKey && e.altKey) || key === 32) {
      playChange(!isPlay.value)
      event.preventDefault()
    }
    if (key === 39 && e.ctrlKey && e.altKey) {
      nextSong()
      event.preventDefault()
    }
    if (key === 37) {
      musicAudio.value.currentTime -= 6
      event.preventDefault()
    }
    if (key === 39) {
      musicAudio.value.currentTime += 6
      event.preventDefault()
    }
  }
</script>
<style>
  /* 歌手名称的动画 */
  @keyframes singerNameMove {
    0% {
      transform: translateX(10px);
    }
    50% {
      transform: translateX(v-bind('-' + flowWidth));
    }
    100% {
      transform: translateX(10px);
    }
  }
  /* 歌词渐变过渡的动画 */
  @keyframes move {
    /* 开始状态 */
    from {
      width: 0%;
    }
    /* 结束状态 */
    to {
      width: 100%;
    }
  }
</style>
<style lang="scss" scoped>
  .console {
    height: 90px;
    :deep(.el-slider__bar) {
      background-color: $musicColor;
    }
    :deep(.el-slider__button) {
      border-color: $musicColor;
      width: 13px;
      height: 13px;
    }

    .content {
      .left {
        width: 120px;
        overflow: hidden;
        .singerNameBox {
          display: inline-block;
        }
        .comment {
          line-height: 25px;
          color: #7b7b7b;
        }
      }

      .play-pause {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        background-color: $musicColor;
        color: #fff;
        text-align: center;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .center {
        & > span:hover {
          color: $musicColor;
        }

        .play-mode {
          color: #000;
        }
      }

      .lyricBox {
        height: 42px;
        overflow: hidden;
        position: relative;
        .lyricContent {
          position: absolute;
          transition: 0.5s;
          left: 50%;
          transform: translateX(-50%);
          .lyricText {
            height: 21px;
            position: relative;
            display: inline-block;

            .lyricGradient {
              position: absolute;
              left: 0;
              top: 0;
              color: $musicColor;
              white-space: nowrap;
              overflow: hidden;
              width: 0%;
              // animation-name: move;
            }
          }
        }
      }
    }
    .right {
      color: #838383;
      .words {
        line-height: 18px;
      }
    }
  }
  .mode-item {
    height: 35px;
    border-bottom: 1px solid rgb(238, 238, 238);
    &:hover {
      background-color: rgb(243, 243, 243);
    }
    &:last-of-type {
      border-bottom: none;
    }
  }
  .drawer-header {
    height: 100px;
  }
  .drawer-content {
    height: calc(100% - 180px);
    overflow: auto;
    .drawer-item {
      &:hover {
        background-color: #efefef;
        & .operation {
          display: block;
        }
      }
      .operation {
        display: none;
      }
    }
  }
  .drader-footer {
    height: 80px;
  }
</style>
